package com.itheima.d4_byte_stream;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Arrays;

/**
 * 目标：掌握使用FileInputStream每次读取多个字节。
 *
 * 注意：
 *      使用FileInputStream每次读取多个字节，读取性能得到了提升，但读取汉字输出还是会乱码。
 * 1、使用字节流读取中文，如何保证输出不乱码，怎么解决？
 *      定义一个与文件一样大的字节数组，一次性读取完文件的全部字节。
 *
 *       * 方法名称
 *  *  public int read()   每次读取一个字节返回，如果发现没有数据可读会返回-1.
 *  *  public int read(byte[] buffer)  每次用一个字节数组去读取数据，返回字节数组读取了多少个字节，如果发现没有数据可读会返回-1.
 *
 *  String(byte[] bytes)       通过使用平台的默认字符集解码指定的字节数组来构造新的 String
 *  String(byte[] bytes, String charsetName)    通过指定的字符集解码指定的字节数组来构造新的 String
 *
 *  重点解惑：
 * 前面案例FileInputStreamTest1.java没有解码，是直接用(char)b1的形式，把字节转换为字符输出。并且int b1 = is.read();返回的是字节
 *  本次案例是用String的方法把字节数组解码，然后输出字符串。这次的int len = is.read(buffer);返回的是读取的字节数
 */
public class FileInputStreamTest2 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个字节输入流对象代表字节输入流管道与源文件接通。
        InputStream is = new FileInputStream("Day08File-Io-App\\src\\itheima02.txt");

/*
        // 2、开始读取文件中的字节数据：每次读取多个字节。
        //  public int read(byte b[]) throws IOException
        //  每次读取多个字节到字节数组中去，返回读取的字节数量，读取完毕会返回-1.

        byte[] buffer = new byte[3];    //长度为三的字节数组
        int len = is.read(buffer);      //就会拿着水桶（字节数组）去每次读取三个字节
        System.out.println("---------------//解码，因为读到的字节是以编码的形式展现的----------");
        String rs = new String(buffer);
        System.out.println("每次读取字节个数： "+len);
        System.out.println("第一次没有解码的返回的字节数组: "+ Arrays.toString(buffer));
        System.out.println("把第一次字节数组解码为字符串： "+rs);

        System.out.println("---------第二次读取---------");

        //这个buffer水桶可以第二次用，新读取的字节会覆盖掉原来的。此时itheima02.txt的内容是abc66，前面已经读取abc
        // 第一次buffer = [abc]
        // 第二次buffer = [66c]        这次只剩下66没读取，所以字节数组的第三个元素“c”还在，没有被覆盖
        int len2 = is.read(buffer);     //第二次读取字节只读了2个
        // 所以这次的字节数组解码输出为： 66c
        //String rs2 = new String(buffer);

        //注意：更改上面这个错误的字节数组输出，0代表从第一个字节开始一直读取，总共读取len2个字节。实现：读取多少，倒出多少。
        String rs2 = new String(buffer, 0, len2);
        System.out.println("每次读取字节个数： "+len2);
        System.out.println("第二次没有解码的返回的字节数组: "+ Arrays.toString(buffer));
        System.out.println("把第二次字节数组解码为字符串： "+rs2);

        System.out.println("-------------第三次读取 ----------------");

        int len3 = is.read(buffer);
        System.out.println(len3); // -1
*/

        //如果有很多字节，就算是上面那种形式，也需要写很多类似的代码，改造一下：

        // 3、使用循环改造。此时itheima02.txt的内容是abc66
        byte[] buffer1 = new byte[3];
        int len1; // 记住每次读取了多少个字节。  第一次循环读取的是abc，所以len1为3，第二次读取的是66，len1为2
        while ((len1 = is.read(buffer1)) != -1){
            // 注意：一定要从零开始，解码的字节个数是len1个。总结就是读取多少，倒出多少。
            String rs1 = new String(buffer1, 0 , len1);
            System.out.print(rs1);
        }
        // 性能得到了明显的提升！！
        // 这种方案也不能避免读取汉字输出乱码的问题！！

        // * ASCII字符集：只有英文、数字、符号等，占1个字节。
        // * GBK字符集：汉字占2个字节，英文、数字占1个字节。
        // * UTF-8字符集：汉字占3个字节，英文、数字占1个字节。
        //本次字节数组设置的为new byte[3]，所以可以正常输出中文不乱码

        is.close(); // 关闭流

        System.out.println();

        System.out.println("------------自己试一试---------");
        InputStream zeng1 = new FileInputStream("Day08File-Io-App\\src\\itheima01.txt");
        byte[] zengbyte = new byte[3];
        int length = zeng1.read(zengbyte);
        System.out.println("每次读取字节的个数： "+length);

        int length1 = 0;
        while ((length1=zeng1.read(zengbyte))!=-1){
            String zengs = new String(zengbyte,0,length1);
            System.out.print(zengs);
        }
        zeng1.close();
    }
}
